package org.nativejpa.datasource;

import org.nativejpa.parser.PersistenceUnit;

import javax.sql.DataSource;
import javax.transaction.TransactionManager;

import org.enhydra.jdbc.standard.StandardXADataSource;
import org.enhydra.jdbc.pool.StandardXAPoolDataSource;

/**
 * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
 * @create 2009-3-24 16:56:29
 */
public class XAPoolDataSourceFactory extends DataSourceFactory {

    public String getVendor() {
        return "XAPool";
    }

    public DataSource createDataSource(PersistenceUnit persistenceUnit, TransactionManager transactionManager) {
        StandardXAPoolDataSource sxpds = new StandardXAPoolDataSource();
        StandardXADataSource sxds = new StandardXADataSource();
        // check connection after checkOut from xapool, if closed, expire it and reconnect
        sxpds.setCheckLevelObject(2); // default 2
        sxpds.setDataSourceName(persistenceUnit.getUnitName());
        try {
            sxds.setDriverName(persistenceUnit.getDataSourceJdbcDriver());
            sxds.setUrl(persistenceUnit.getDataSourceJdbcURL());
            sxpds.setUser(persistenceUnit.getDataSourceJdbcUsername());
            sxds.setUser(persistenceUnit.getDataSourceJdbcUsername());
            sxpds.setPassword(persistenceUnit.getDataSourceJdbcPassword());
            sxds.setPassword(persistenceUnit.getDataSourceJdbcPassword());
            if (persistenceUnit.getDataSourcePoolTestQuery() != null && !persistenceUnit.getDataSourcePoolTestQuery().trim().equals("")) {
                sxpds.setJdbcTestStmt(persistenceUnit.getDataSourcePoolTestQuery());
            }

            sxpds.setMinSize(persistenceUnit.getDataSourcePoolMinSize());
            sxpds.setMaxSize((persistenceUnit.getDataSourcePoolMaxSize()));
            sxpds.setLifeTime(24 * 60 * 60 * 1000); // 24h
            sxpds.setSleepTime(persistenceUnit.getDataSourcePoolMaxIdleTime() * 1000);
            sxpds.setDeadLockRetryWait(persistenceUnit.getDataSourcePoolConnectTimeout() * 1000);
            sxpds.setDeadLockMaxWait(2 * 60 * 1000); // max 5m
        }
        catch (Exception e) {
            throw new DataSourceException("Failed to create data source: " + persistenceUnit.getUnitName(), e);
        }
        // must setTransactionManager before setDataSource, so sxpds can setTM to sxds
        sxpds.setTransactionManager(transactionManager);
        sxpds.setDataSource(sxds);
        return sxpds;
    }

    public void shutdownDataSource(DataSource dataSource) {
        ((StandardXAPoolDataSource)dataSource).shutdown(false);
    }
}